package com.seawave.sdkclientjdk11.util;

import com.google.gson.Gson;
import com.seawave.sdkclientjdk11.vo.enums.HttpMethod;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
 * HTTP协议工具类
 * Created by 黄鹏祥 on 2017/6/29.
 */
public class HttpUtil {

    private final static Gson GSON = GsonSingletonUtil.getInstance();

    /**
     * 发送json请求，并将响应结果转成json
     *
     * @param requestUrl
     * @param method
     * @param json
     * @return
     */
    public static Map<String, Object> postJson2JsonObject(final String requestUrl, final HttpMethod method, final String json) {
        String reStr = postJson(requestUrl, method, json);
        Map<String, Object> jsonObject = GSON.fromJson(reStr, Map.class);
        return jsonObject;
    }

    /**
     * 发送json请求
     *
     * @param requestUrl
     * @param method
     * @param json
     */
    public static String postJson(final String requestUrl, final HttpMethod method, final String json) {
//        响应字符串
        String reStr = null;
        try {
            //创建连接
            URL url = new URL(requestUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod(method.getMethod());
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8;");
            connection.setRequestProperty("Accept", "application/json;charset=utf-8;");
            connection.setConnectTimeout(120 * 1000);
            connection.setReadTimeout(120 * 1000);
            connection.connect();

            //POST请求
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());

            out.writeBytes(json);
            out.flush();
            out.close();

            //读取响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String lines;
            StringBuffer sb = new StringBuffer("");
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }
            reStr = sb.toString();
            reader.close();
            // 断开连接
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reStr;
    }

    /**
     * 发送http请求
     *
     * @param requestUrl
     * @param requestMethod
     * @param outputStr
     * @return
     */
    public static Map<String, Object> httpRequest(String requestUrl, String requestMethod, String outputStr) {
        Map<String, Object> jsonObject = null;
        try {
            URL url = new URL(requestUrl);
//            URLConnection conn =  url.openConnection();

            URLConnection conn = url.openConnection();

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
//            conn.setRequestMethod(requestMethod);
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
//            conn.disconnect();
//            jsonObject = JSONObject.fromObject(buffer.toString());
            jsonObject = GSON.fromJson(buffer.toString(), Map.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
     * 发送https请求
     *
     * @param requestUrl
     * @param requestMethod
     * @param outputStr
     * @return
     */
    public static Map<String, Object> httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        Map<String, Object> jsonObject = null;
        try {
            TrustManager[] tm = {new JEEWeiXinX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();
//            URL url = new URL(null, requestUrl, new sun.net.www.protocol.https.Handler());
            URL url = new URL( requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
//            jsonObject = JSONObject.fromObject(buffer.toString());
            jsonObject = GSON.fromJson(buffer.toString(), Map.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    private static class JEEWeiXinX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    /**
     * 重定向
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param url
     */
    public static void redirectUrl(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, String url) {
        try {
            httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 重定向到http://的url
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param url
     */
    public static void redirectHttpUrl(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, String url) {
        try {
            httpServletResponse.sendRedirect(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getRequestFullUri(HttpServletRequest request) {
        return request.getScheme() + "://" + request.getServerName() + request.getContextPath() + request.getServletPath();
    }

    /**
     * 输入流转字节数组
     *
     * @param is
     * @return
     * @throws IOException
     */
    public static byte[] getBytesInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[512];
        int len;
        while ((len = is.read(buff)) != -1) {
            arrayOutputStream.write(buff, 0, len);
        }
        is.close();
        arrayOutputStream.close();
        return arrayOutputStream.toByteArray();
    }

    /**
     * 发送json请求(下载)
     *
     * @param requestUrl
     * @param method
     * @param json
     */
    public static String postJson4Download(final String requestUrl, final HttpMethod method, final String json) {
//        响应字符串
        String reStr = null;
        try {
            //创建连接
            URL url = new URL(requestUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod(method.getMethod());
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8;");
            connection.setRequestProperty("Accept", "application/json;charset=utf-8;");
            connection.setConnectTimeout(120 * 1000);
            connection.setReadTimeout(120 * 1000);
            connection.connect();

            //POST请求
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());

            out.writeBytes(json);
            out.flush();
            out.close();

            //读取响应
            InputStream in = connection.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            reStr = new String(baos.toByteArray());
            baos.close();
            in.close();

            // 断开连接
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reStr;
    }

}
